/*!\file  sched.h  The scheduler and context switch stuff.
 *
 *      This file is part of the micro-rtos package.
 *
 *  Copyright (c) 2008-2009 by 
		Gabriel Zabusek <gabriel.zabusek@gmail.com>
 *
 *      This program is free software; you can redistribute it and/or
 *      modify it under the terms of the GNU General Public License
 *      as published by the Free Software Foundation; either version
 *      2 of the License, or (at your option) any later version.
 */

#ifndef __SCHED_H
#define __SCHED_H

#include <kernel/task.h>
#include <include/types.h>
#include <include/std_io.h>

volatile bool_t bSchedulingStart;
volatile bool_t bFirstRestore;

typedef volatile struct CONTEXT{
	volatile unative_t r0;
	volatile unative_t r1;
	volatile unative_t r2;
	volatile unative_t r3;
	volatile unative_t r4;
	volatile unative_t r5;
	volatile unative_t r6;
	volatile unative_t r7;
	volatile unative_t r8;
	volatile unative_t r9;
	volatile unative_t r10;
	volatile unative_t r11;
	volatile unative_t r12;
	volatile unative_t sp;
	volatile unative_t lr;
	volatile unative_t pc;
} context_t;

static inline void 
RestoreContext(unative_t *pSP)
{
	//printk("pSP_B %p\n",pSP);

	asm volatile(
	"LDR	LR, %0\n"
	"LDMFD	LR!, {R0}\n" 	  //get spsr
	"MSR	SPSR, R0\n"  	  //restore spsr
	"LDMFD	LR, {R0-R14}^\n"  //restore all other registers
	"NOP\n"
	"LDR	LR, [LR, #+60]\n"
	"SUBS	PC, LR, #4\n"
	:
	: "m"(pSP)
	: "memory"
	);

	//printk("pSP_A %p\n",pSP);

}

static inline void
SaveContext(unative_t *pSP)
{

	asm volatile(
	"STMDB	SP!, {R0}\n"
	"STMDB	SP,{SP}^\n"
	"NOP\n"
	"SUB	SP, SP, #4\n"
	"LDMIA	SP!,{R0}\n"
	"STMDB	R0!, {LR}\n"
	"MOV	LR, R0\n"
	"LDMIA	SP!, {R0}\n"
	"STMDB	LR,{R0-R14}^\n"
	"NOP\n"
	"SUB	LR, LR, #60\n"
	"MRS	R0, SPSR\n\t"
	"STMDB	LR!, {R0}\n"
	"LDR	R0, =pCurTaskStackTop\n"
	"STR	LR, [R0]\n"
	);					

}



#endif
